package com.sec.etech.form.rest.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import org.openbpm.base.api.Page;
import org.openbpm.base.api.query.FieldRelation;
import org.openbpm.base.api.query.QueryFilter;
import org.openbpm.base.api.query.QueryOP;
import org.openbpm.base.api.query.WhereClause;
import org.openbpm.base.core.util.AppUtil;
import org.openbpm.base.core.util.BeanUtils;
import org.openbpm.base.core.util.StringUtil;
import org.openbpm.base.core.util.ThreadMapUtil;
import org.openbpm.base.dao.CommonDao;
import org.openbpm.base.db.model.query.DefaultQueryField;
import org.openbpm.form.api.constant.FormCustDialogConditionFieldValueSource;
import org.openbpm.form.api.constant.FormCustDialogStyle;
import org.openbpm.form.manager.impl.FormCustDialogManagerImpl;
import org.openbpm.form.model.FormCustDialog;
import org.openbpm.form.model.custdialog.FormCustDialogConditionField;
import org.openbpm.form.model.custdialog.FormCustDialogDisplayField;
import org.openbpm.form.model.custdialog.FormCustDialogReturnField;
import org.openbpm.form.model.custdialog.FormCustDialogSortField;
import org.openbpm.sys.api.groovy.IGroovyScriptEngine;
import org.openbpm.sys.api.service.ISysDataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

@Primary
@Service("etechFormCustDialogManager")
public class EtechFormCustDialogManager extends FormCustDialogManagerImpl {

    @Autowired
    ISysDataSourceService sysDataSourceService;
    @Autowired
    CommonDao<?> commonDao;
    @Autowired
    IGroovyScriptEngine groovyScriptEngine;

    public List<?> data(FormCustDialog formCustDialog, QueryFilter queryFilter) {
        String sql = this.analyseSql(formCustDialog);
        this.handleQueryFilter(formCustDialog, queryFilter);
        boolean isPage = (Boolean) ThreadMapUtil.getOrDefault("isPage", true);
        if (!isPage) {
            queryFilter.setPage((Page) null);
        }
        if ("interface".equals(formCustDialog.getDataSource())) {
            if (StrUtil.isNotBlank(sql)) {
                queryFilter.addParamsFilter("sql", sql);
            }
            queryFilter.addParamsFilter("formCustDialog", formCustDialog);
            queryFilter.addParamsFilter("objName", formCustDialog.getObjName());
            return this.getDataByInterface(formCustDialog, queryFilter);
        } else {
            List list = this.commonDao.queryForListPage(sql, queryFilter);
            return list;
        }
    }

    private List getDataByInterface(FormCustDialog customDialog, QueryFilter queryFilter) {
        String beanMethod = customDialog.getObjName();
        if (StringUtil.isEmpty(beanMethod)) {
            throw new RuntimeException("自定义对话框数据服务接口不能为空！");
        } else {
            String[] aryHandler = beanMethod.split("[.]");
            if (aryHandler != null && aryHandler.length == 2) {
                String beanId = aryHandler[0];
                String method = aryHandler[1];
                Object serviceBean = AppUtil.getBean(beanId);
                if (serviceBean == null) {
                    return null;
                } else {
                    try {
                        Method invokeMethod = serviceBean.getClass().getDeclaredMethod(method, QueryFilter.class);
                        return (List)invokeMethod.invoke(serviceBean, queryFilter);
                    } catch (Exception var9) {
                        throw new RuntimeException("查询异常！" + var9.getMessage(), var9);
                    }
                }
            } else {
                throw new RuntimeException("自定义对话框数据服务接口格式不正确！" + beanMethod);
            }
        }
    }

    private String analyseSql(FormCustDialog formCustDialog) {
        Set<String> columnNameSet = new HashSet();
        Iterator var3;
        if (FormCustDialogStyle.LIST.equalsWithKey(formCustDialog.getStyle())) {
            var3 = formCustDialog.getDisplayFields().iterator();

            while(var3.hasNext()) {
                FormCustDialogDisplayField field = (FormCustDialogDisplayField)var3.next();
                columnNameSet.add(field.getColumnName());
            }
        }

        if (FormCustDialogStyle.TREE.equalsWithKey(formCustDialog.getStyle())) {
            columnNameSet.add(formCustDialog.getTreeConfig().getPid());
            columnNameSet.add(formCustDialog.getTreeConfig().getId());
            columnNameSet.add(formCustDialog.getTreeConfig().getShowColumn());
        }

        var3 = formCustDialog.getReturnFields().iterator();

        while(var3.hasNext()) {
            FormCustDialogReturnField field = (FormCustDialogReturnField)var3.next();
            columnNameSet.add(field.getColumnName());
        }

        var3 = formCustDialog.getSortFields().iterator();

        while(var3.hasNext()) {
            FormCustDialogSortField field = (FormCustDialogSortField)var3.next();
            columnNameSet.add(field.getColumnName());
        }

        StringBuilder displaySql = new StringBuilder();

        String columnName;
        for(Iterator var9 = columnNameSet.iterator(); var9.hasNext(); displaySql.append(columnName)) {
            columnName = (String)var9.next();
            if (displaySql.length() > 0) {
                displaySql.append(",");
            }
        }

        return "select " + displaySql.toString() + " from " + formCustDialog.getObjName();
    }

    private QueryFilter handleQueryFilter(FormCustDialog formCustDialog, QueryFilter queryFilter) {
        Iterator var3 = formCustDialog.getConditionFields().iterator();

        while(var3.hasNext()) {
            FormCustDialogConditionField field = (FormCustDialogConditionField)var3.next();
            FieldRelation fieldRelation = null;
            if ("OR".equalsIgnoreCase(field.getFieldRelation())) {
                fieldRelation = FieldRelation.OR;
            } else if ("AND".equalsIgnoreCase(field.getFieldRelation())) {
                fieldRelation = FieldRelation.AND;
            }

            Object value;
            if (FormCustDialogConditionFieldValueSource.FIXED_VALUE.equalsWithKey(field.getValueSource())) {
                value = getValue(field.getDbType(), QueryOP.getByVal(field.getCondition()), field.getValue().getText());
                queryFilter.addFilter(field.getColumnName(), value, QueryOP.getByVal(field.getCondition()), fieldRelation);
            } else if (FormCustDialogConditionFieldValueSource.SCRIPT.equalsWithKey(field.getValueSource())) {
                value = this.groovyScriptEngine.executeObject(field.getValue().getText(), queryFilter.getParams());
                queryFilter.addFilter(field.getColumnName(), value, QueryOP.getByVal(field.getCondition()), fieldRelation);
            }

            if (FormCustDialogConditionFieldValueSource.PARAM.equalsWithKey(field.getValueSource())) {
                Iterator var10 = queryFilter.getFieldLogic().getWhereClauses().iterator();

                while(var10.hasNext()) {
                    WhereClause whereClause = (WhereClause)var10.next();
                    if (whereClause instanceof DefaultQueryField) {
                        DefaultQueryField queryField = (DefaultQueryField)whereClause;
                        if (field.getColumnName().equalsIgnoreCase(queryField.getField())) {
                            queryField.setFieldRelation(fieldRelation);
                        }
                    }
                }
            }
        }

        var3 = formCustDialog.getSortFields().iterator();

        while(var3.hasNext()) {
            FormCustDialogSortField field = (FormCustDialogSortField)var3.next();
            queryFilter.addFieldSort(field.getColumnName(), field.getSortType());
        }

        return queryFilter;
    }

    public static Object getValue(String columnType, QueryOP queryOP, String valStr) {
        String[] strs = new String[1];
        strs[0] = valStr;
        if (queryOP.equals(QueryOP.getByVal("IN")) || queryOP.equals(QueryOP.getByVal("NI"))) {
            strs = valStr.split(",");
            if ("varchar".equals(columnType)) {
                return valStr;
            }else {
                List vals = new ArrayList();
                for (String str : strs) {
                    if ("number".equals(columnType)){
                        try {
                            if (str != null) {
                                if (str.length() > 18) {
                                    if (str.indexOf(".") > 0) {
                                        vals.add(new BigDecimal(str));
                                    } else {
                                        vals.add(new BigInteger(str));
                                    }
                                } else if (str.indexOf(".") >= 0) {
                                    vals.add(Double.parseDouble(str));
                                } else {
                                    vals.add(Long.parseLong(str));
                                }
                            }
                        } catch (Exception var7) {
                        }

                        try {
                            if (str == null) {
                                vals.add(Double.parseDouble(str));
                            }
                        } catch (Exception var6) {
                        }
                    } else if ("date".equals(columnType)) {
                        try {
                            vals.add(DateUtil.parse(valStr));
                        } catch (Exception var5) {
                        }
                    }
                }
                return vals;
            }
        }
        Object value = null;
        if ("varchar".equals(columnType)) {
            value = valStr;
        } else if ("number".equals(columnType)) {
            try {
                if (valStr != null) {
                    if (valStr.length() > 18) {
                        if (valStr.indexOf(".") > 0) {
                            value = new BigDecimal(valStr);
                        } else {
                            value = new BigInteger(valStr);
                        }
                    } else if (valStr.indexOf(".") >= 0) {
                        value = Double.parseDouble(valStr);
                    } else {
                        value = Long.parseLong(valStr);
                    }
                }
            } catch (Exception var7) {
            }

            try {
                if (value == null) {
                    value = Double.parseDouble(valStr);
                }
            } catch (Exception var6) {
            }
        } else if ("date".equals(columnType)) {
            try {
                value = DateUtil.parse(valStr);
            } catch (Exception var5) {
            }
        }

        return value;
    }
}
